/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2008-2011, Salzburg Research. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * - Neither the name of the KiWi Project nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Contributor(s):
 * tkurz
 *
 * File Info:
 * User: tkurz
 * Date: 2011/01/18
 * Time: 16:50
 *
 * Project: KiWi2, kiwi-core module
 */

package kiwi.core.services.sesame;

import kiwi.core.model.Constants;
import kiwi.core.model.rdf.*;
import org.hibernate.proxy.HibernateProxy;
import org.openrdf.model.*;
import org.openrdf.repository.Repository;

/**
 * Add file description here!
 * <p/>
 * User: sschaffe
 */
public class KiWiSesameUtil {


    /**
      * Transform a KiWi node into a Sesame value; differentiates between the different types of nodes
      * and returns appropriate Sesame values:
      * <ul>
      * 	<li>a KiWiUriResource is transformed into a Sesame URI</li>
      *  <li>a KiWiAnonResource is transformed into a Sesame BNode</li>
      *  <li>a KiWiLiteral is transformed into a Sesame Literal</li>
      * </ul>
      *
      * @param repository the repository in which the node is to be represented
      * @param kiwi the KiWiNode to transform
      * @return the Sesame node object
      */
     public static Value transformKiWiToSesame(Repository repository,KiWiNode kiwi) {
         ValueFactory f = repository.getValueFactory();

         return transformKiWiToSesame(f,kiwi);
     }

     /**
      * Transform a KiWi node into a Sesame value; differentiates between the different types of nodes
      * and returns appropriate Sesame values:
      * <ul>
      * 	<li>a KiWiUriResource is transformed into a Sesame URI</li>
      *  <li>a KiWiAnonResource is transformed into a Sesame BNode</li>
      *  <li>a KiWiLiteral is transformed into a Sesame Literal</li>
      * </ul>
      * This method may be used to create a Sesame Value outside the original triple store.
      *
      * @param f the value factory to use for creating the node
      * @param kiwi the KiWiNode to transform
      * @return the Sesame node object
      */
     public static Value transformKiWiToSesame(ValueFactory f,KiWiNode kiwi) {

         if(kiwi == null) {
             return null;
         }

         // work around lazy Hibernate proxies; I hate the visitor pattern, but Hibernate enforces
         // it - this piece of code works around it...
         if (kiwi instanceof HibernateProxy) {
             return transformKiWiToSesame(f,(KiWiNode)((HibernateProxy)kiwi).getHibernateLazyInitializer().getImplementation());
         }

         if(kiwi.isUriResource()) {
             return f.createURI(((KiWiUriResource)kiwi).getUri());
         } else if(kiwi.isAnonymousResource()) {
             return f.createBNode(((KiWiAnonResource)kiwi).getAnonId());
         } else if(kiwi.isLiteral()) {
             KiWiLiteral l = (KiWiLiteral)kiwi;
             if(l.getType().equals(Constants.NS_XSD+"integer")) {
                 return f.createLiteral(Integer.parseInt(l.getContent()));
             } else if(l.getType().equals(Constants.NS_XSD+"long")) {
                 return f.createLiteral(Long.parseLong(l.getContent()));
             } else if(l.getType().equals(Constants.NS_XSD+"boolean")) {
                 return f.createLiteral(Boolean.parseBoolean(l.getContent()));
             } else if(l.getType().equals(Constants.NS_XSD+"double")) {
                 return f.createLiteral(Double.parseDouble(l.getContent()));
             } else if(l.getType().equals(Constants.NS_XSD+"float")) {
                 return f.createLiteral(Float.parseFloat(l.getContent()));
             } else {
                 return f.createLiteral(l.getContent().toString(), l.getLanguage()!=null?l.getLanguage().getLanguage():null);
             }

         } else {
             return null;
         }
      }

     /**
      * Transform a KiWi triple into a Sesame statement.
      *
      * @param repository the triple store in which the triple is to be represented
      * @param triple the KiWiTriple to convert
      * @return
      */
     public static Statement transformKiWiToSesame(Repository repository, KiWiTriple triple) {
         ValueFactory f = repository.getValueFactory();
         return transformKiWiToSesame(f,triple);
     }


     /**
      * Transform a KiWi triple into a Sesame statement. This method may be used to create a
      * Sesame Statement outside the original triple store.
      *
      * @param f the value factory to use for creating the sesame statement
      * @param triple triple the KiWiTriple to convert
      * @return
      */
     public static Statement transformKiWiToSesame(ValueFactory f, KiWiTriple triple) {
         return f.createStatement(
                 (Resource) transformKiWiToSesame(f,triple.getSubject()),
                 (URI)      transformKiWiToSesame(f,triple.getProperty()),
                            transformKiWiToSesame(f,triple.getObject()),
                 (Resource) transformKiWiToSesame(f,triple.getContext()) );
     }


}
